;;;; Defines the EVPL interpreter.
;;;; Copyright (C) 2009 David J. Rosenbaum, email: davidjrosenbaum@comcast.net
;;;;
;;;; This program is free software: you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation, under version 3 of the License.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;;;
;;;; Copyright (C) 2009 David J. Rosenbaum
;;;; This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
;;;; This is free software, and you are welcome to redistribute it
;;;; under certain conditions; for details see COPYING.

(in-package :evpl)

(defun interpreter (&key (input-stream *standard-input*) (output-stream *standard-output*) (error-stream *error-output*))
  "Reads and executes the input from stream and evaluates it until an EOF is encountered.  Returns nil."
  (loop
     for lexer = (cl-lex:stream-lexer #'read-source-line
				       #'string-lexer
				       #'opening-delimiter-p
				       #'closing-delimiter-p
				       :stream input-stream) do
       (format output-stream "~&EVPL> ")
       (finish-output output-stream)
       (handler-case (princ (eval (parse lexer)) output-stream)
	 (end-of-file () (return))
	 (error (condition)
	   (print (typecase condition
		    (yacc:yacc-parse-error (format nil "syntax error: ~a" condition))
		    (t (format nil "runtime error: ~a" condition)))
		  error-stream)
	   (finish-output error-stream)
	   (cerror "Skip to the next statement" condition)))))
